﻿#region Opis pliku
//-----------------------------------------------------------------------------
// LoadingScreen.cs
// Autor: Jan Czarnowski
// 6.11.2012
//-----------------------------------------------------------------------------
#endregion

#region Using...

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Collections.Generic;
using System;

#endregion

namespace pogra
{
    /// <summary>
    /// Klasa obslugująca przejścia pomiędzy stanem menu a stanem gry.
    /// </summary>
    class LoadingScreen : GameScreen
    {
        #region pola

        GameScreen[] screensToLoad;
        TimeSpan loadTime;
        TimeSpan timeRemaining;
        bool slowLoad;
        int numOfScreens;
        private bool fadingOut;
        private bool fadingIn;

        #endregion

        #region inicjalizacja

        /// <summary>
        /// Tworzy nowy obiekt LoadingScreen
        /// </summary>
        /// <param name="screenManager">Aktualna instancja ScreenManager</param>
        /// <param name="slowLoad">Czy ładowanie ma być wolne?</param>
        /// <param name="screensToLoad">Obiekty GameScreen, które mają być wczytane</param>
        public LoadingScreen(ScreenManager screenManager, bool slowLoad, params GameScreen[] screensToLoad)
        {
            this.screensToLoad = screensToLoad;
            this.timeRemaining = TimeSpan.FromSeconds(1);
            this.loadTime = timeRemaining;
            this.slowLoad = slowLoad;
            this.ScreenManager = screenManager;
            this.numOfScreens = ScreenManager.GetScreens().Length;

            fadingOut = true;
            fadingIn = false;
        }

        #endregion

        #region metody draw i update

        /// <summary>
        /// 
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Draw(GameTime gameTime)
        {
            // odwracamy transformację aby zaciemniac caly ekran((RTSGame)ScreenManager.Game).Camera.Zoom
            //Matrix inverseTransform = Matrix.Invert(((RTSGame) ScreenManager.Game).Camera.GetTransformation(ScreenManager.Game.GraphicsDevice));
            //Vector2 size = Vector2.Transform(new Vector2(ScreenManager.ViewRect.Width, ScreenManager.ViewRect.Height), Matrix.Invert(Matrix.CreateScale(((RTSGame) ScreenManager.Game).Camera.Zoom)));
            //Vector2 pos = Vector2.Transform(new Vector2(ScreenManager.ViewRect.X, ScreenManager.ViewRect.Y), inverseTransform);
            ExtendedSpriteBatch exSpriteBatch = ScreenManager.ExtendedSpriteBatch;
            exSpriteBatch.End();
            exSpriteBatch.Begin();

            exSpriteBatch.FillRectangle(ScreenManager.ViewRect, Color.Black * (float)(1 - timeRemaining.TotalMilliseconds / loadTime.TotalMilliseconds));
            
            exSpriteBatch.End();

            RTSGame game = ((RTSGame)ScreenManager.Game);
            exSpriteBatch.Begin(SpriteSortMode.Deferred,
                                BlendState.AlphaBlend,
                                null,
                                null,
                                null,
                                null,
                               game.Camera.GetTransformation(game.GraphicsDevice));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Update(GameTime gameTime)
        {
            if (slowLoad)
            {
                if (timeRemaining > TimeSpan.Zero && fadingOut)
                    timeRemaining -= gameTime.ElapsedGameTime;

                if (fadingIn && timeRemaining < loadTime)
                    timeRemaining += gameTime.ElapsedGameTime;

                if (timeRemaining <= TimeSpan.Zero)
                {
                    fadingOut = false;
                    fadingIn = true;

                    foreach (GameScreen screen in ScreenManager.GetScreens())
                        screen.Exit();

                    ScreenManager.RemoveScreen(this);

                    foreach (GameScreen screen in screensToLoad)
                    {
                        if (screen != null)
                        {
                            ScreenManager.AddScreen(screen);
                        }
                    }

                    ScreenManager.AddScreen(this);
                }

                if (timeRemaining >= loadTime && fadingIn)
                    ScreenManager.RemoveScreen(this);
            }
            else
            {
                foreach (GameScreen screen in screensToLoad)
                {
                    if (screen != null)
                    {
                        ScreenManager.AddScreen(screen);
                    }
                }
            }
        }

        #endregion

        #region metody publiczne

        /// <summary>
        /// 
        /// </summary>
        /// <param name="screenManager"></param>
        /// <param name="screensToLoad"></param>
        public static void Load(ScreenManager screenManager, bool slowLoad, params GameScreen[] screensToLoad)
        {
            LoadingScreen loadingScreen = new LoadingScreen(screenManager, slowLoad, screensToLoad);

            screenManager.AddScreen(loadingScreen);
        }

        #endregion
    }
}
